﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Reflection;

namespace VS.Infrastructure.Controls
{
    public class SelectorBehaviors : DependencyObject
    {
        #region ZIndexSetOnSelection
        public static readonly DependencyProperty IsZIndexSetOnSelectionProperty = DependencyProperty.RegisterAttached(
           "IsZIndexSetOnSelection", typeof(bool), typeof(SelectorBehaviors),
           new PropertyMetadata(ZIndexSettingChanged));

        public static bool GetIsZIndexSetOnSelection(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsZIndexSetOnSelectionProperty);
        }

        public static void SetIsZIndexSetOnSelection(
            DependencyObject obj, bool value)
        {
            obj.SetValue(IsZIndexSetOnSelectionProperty, value);
        }

        private static void ZIndexSettingChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (obj is Selector)
            {
                var selector = obj as Selector;
                selector.SelectionChanged += (s, e) =>
                {
                    if (selector.SelectedItem != null)
                        foreach (var pair in ItemsControlExtensions.GetItemsAndContainers(selector))
                            pair.Value.SetValue(Canvas.ZIndexProperty, (pair.Key == selector.SelectedItem) ? 1 : 0);
                };

                selector.MouseMove += (s, e) =>
                {
                    Type containerType = selector.ItemContainerGenerator.ContainerFromIndex(0).GetType();
                    FrameworkElement element = e.OriginalSource as FrameworkElement;
                    FrameworkElement container = element.GetVisualAncestors().First(x => containerType.IsAssignableFrom(x.GetType())) as FrameworkElement;
                    foreach (var pair in ItemsControlExtensions.GetItemsAndContainers(selector))
                        if (pair.Key != selector.SelectedItem)
                            pair.Value.SetValue(Canvas.ZIndexProperty, (pair.Value == container) ? 1 : 0);
                };
            }
        }
        #endregion

        #region CommandPathProperty

        public static readonly DependencyProperty CommandPathProperty = DependencyProperty.RegisterAttached(
           "CommandPath", typeof(string), typeof(SelectorBehaviors),
           new PropertyMetadata(CommandPathChanged));

        public static string GetCommandPath(DependencyObject obj)
        {
            return (string)obj.GetValue(CommandPathProperty);
        }

        public static void SetCommandPath(
            DependencyObject obj, string value)
        {
            obj.SetValue(CommandPathProperty, value);
        }

        private static void CommandPathChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (obj is Selector)
            {
                var selector = obj as Selector;
                selector.SelectionChanged += (s, e) =>
                {
                    if (selector.SelectedItem != null)
                        foreach (var pair in ItemsControlExtensions.GetItemsAndContainers(selector))
                            if (pair.Key == selector.SelectedItem)
                            {
                                string path = (string)selector.GetValue(SelectorBehaviors.CommandPathProperty);
                                PropertyInfo pi = pair.Key.GetType().GetProperty(path);
                                if (pi != null)
                                {
                                    ICommand command = pi.GetValue(pair.Key, null) as ICommand;
                                    command.Execute(selector.SelectedItem);
                                }
                            }
                };
            }
        }

        #endregion
    }
}
